use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::path::Path;
use flate2::read::GzDecoder;
use regex::Regex;
use chrono::{DateTime, Utc, NaiveDateTime};
use crate::models::{LogEntry, ImportOptions};

pub struct LogParser {
    options: ImportOptions,
}

impl LogParser {
    pub fn new(options: ImportOptions) -> Self {
        Self { options }
    }

    pub fn parse_file(&self, file_path: &str) -> io::Result<Vec<LogEntry>> {
        let path = Path::new(file_path);
        let file = File::open(path)?;
        
        let reader: Box<dyn BufRead> = if path.extension().and_then(|s| s.to_str()) == Some("gz") {
            Box::new(BufReader::new(GzDecoder::new(file)))
        } else {
            Box::new(BufReader::new(file))
        };

        let mut entries = Vec::new();
        let mut line_number = 0;

        for line in reader.lines() {
            line_number += 1;
            let line = line?;
            
            if let Some(entry) = self.parse_line(&line, file_path, line_number) {
                entries.push(entry);
            }
        }

        Ok(entries)
    }

    fn parse_line(&self, line: &str, file_path: &str, line_number: i32) -> Option<LogEntry> {
        // 尝试解析标准日志格式
        if let Some(entry) = self.parse_standard_log(line, file_path, line_number) {
            return Some(entry);
        }

        // 尝试解析JSON格式
        if let Some(entry) = self.parse_json_log(line, file_path, line_number) {
            return Some(entry);
        }

        // 如果都失败，创建原始条目
        Some(LogEntry {
            id: None,
            timestamp: Utc::now(),
            level: "UNKNOWN".to_string(),
            source: "unknown".to_string(),
            message: line.to_string(),
            file_path: file_path.to_string(),
            line_number: Some(line_number),
            raw_content: line.to_string(),
        })
    }

    fn parse_standard_log(&self, line: &str, file_path: &str, line_number: i32) -> Option<LogEntry> {
        // 标准日志格式: [2024-01-01 10:00:00] [INFO] [source] message
        let re = Regex::new(r"\[([^\]]+)\]\s*\[([^\]]+)\]\s*\[([^\]]+)\]\s*(.+)").ok()?;
        
        if let Some(captures) = re.captures(line) {
            let timestamp_str = captures.get(1)?.as_str();
            let level = captures.get(2)?.as_str().to_string();
            let source = captures.get(3)?.as_str().to_string();
            let message = captures.get(4)?.as_str().to_string();

            if let Ok(timestamp) = self.parse_timestamp(timestamp_str) {
                return Some(LogEntry {
                    id: None,
                    timestamp,
                    level,
                    source,
                    message,
                    file_path: file_path.to_string(),
                    line_number: Some(line_number),
                    raw_content: line.to_string(),
                });
            }
        }

        None
    }

    fn parse_json_log(&self, line: &str, file_path: &str, line_number: i32) -> Option<LogEntry> {
        // 尝试解析JSON格式
        if let Ok(json) = serde_json::from_str::<serde_json::Value>(line) {
            let timestamp = json.get("timestamp")
                .and_then(|t| t.as_str())
                .and_then(|s| self.parse_timestamp(s).ok())
                .unwrap_or_else(Utc::now);

            let level = json.get("level")
                .and_then(|l| l.as_str())
                .unwrap_or("UNKNOWN")
                .to_string();

            let source = json.get("source")
                .and_then(|s| s.as_str())
                .unwrap_or("unknown")
                .to_string();

            let message = json.get("message")
                .and_then(|m| m.as_str())
                .unwrap_or(line)
                .to_string();

            return Some(LogEntry {
                id: None,
                timestamp,
                level,
                source,
                message,
                file_path: file_path.to_string(),
                line_number: Some(line_number),
                raw_content: line.to_string(),
            });
        }

        None
    }

    fn parse_timestamp(&self, timestamp_str: &str) -> Result<DateTime<Utc>, chrono::ParseError> {
        // 尝试多种时间格式
        let formats = [
            "%Y-%m-%d %H:%M:%S",
            "%Y-%m-%dT%H:%M:%S",
            "%Y-%m-%dT%H:%M:%S.%f",
            "%Y-%m-%d %H:%M:%S.%f",
        ];

        for format in &formats {
            if let Ok(naive) = NaiveDateTime::parse_from_str(timestamp_str, format) {
                return Ok(DateTime::from_naive_utc_and_offset(naive, Utc));
            }
        }

        // 如果都失败，返回当前时间
        Ok(Utc::now())
    }
} 